#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <set>
#include<unistd.h>
#include<sys/epoll.h>
#include"Log.hpp"

namespace EpollerModule
{
    const static int defaultepfd=-1;
    const static int size=128;
    class Epoller
    {
        public:
        Epoller():_epfd(defaultepfd)
        {

        }
        void initEpoller()
        {
            _epfd=::epoll_create(size);
             if (defaultepfd == _epfd)
            {
                lg.LogMessage(Fatal, "epoll_create error, %s : %d\n", strerror(errno), errno);
                exit(4);
            }
            lg.LogMessage(Info, "epoll_create success, epfd: %d\n", _epfd);
        }

        void AddEvent(int sockfd,uint32_t events)
        {
            fd_list.insert(sockfd);
            struct epoll_event ev;
            ev.events=events;
            ev.data.fd=sockfd;
            int n=::epoll_ctl(_epfd,EPOLL_CTL_ADD,sockfd,&ev);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll_ctl add error, %s : %d\n", strerror(errno), errno);
            }
        }
        void DelEvent(int sockfd)
        {
            fd_list.erase(sockfd);
            int n=::epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,nullptr);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll_ctl del error, %s : %d\n", strerror(errno), errno);
            }
        }
         void DebugFdList()
        {
            std::cout << "fd list is : ";
            for(auto &fd : fd_list)
            {
                std::cout << fd << " ";
            }
            std::cout << std::endl;
        }
        int Wait(struct epoll_event *revs,int maxevents,int timeout)
        {
            int n=::epoll_wait(_epfd,revs,maxevents,timeout);
            return n;
        }

        void ModEvent(int sockfd,uint32_t events)
        {
            struct epoll_event ev;
            ev.events=events;
            ev.data.fd=sockfd;
            int n=::epoll_ctl(_epfd,EPOLL_CTL_MOD,sockfd,&ev);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll_ctl mod error, %s : %d\n", strerror(errno), errno);
            }
        }
         ~Epoller()
        {
            if (_epfd >= 0)
            {
                close(_epfd);
            }
            lg.LogMessage(Info, "epoll close success\n");
        }


        private:
        int _epfd;
        std::set<int> fd_list;
    };







}